package com.neusoft.bizcore.web.utils;

import java.util.ArrayList;
import java.util.List;

import com.neusoft.bizcore.web.bean.TreeBean;
import com.neusoft.bizcore.web.exception.UnitedException;

/**
 * @description: 基于TreeBean的构造树的通用类，务必在TreeBean的attr中加入id和parentId属性
 * @author: wangsi
 * @createTime: 2019年9月6日 下午2:26:54
 * @version: v1.0
 */

public class BuildTreeUtil {

    List<TreeBean> nodes = new ArrayList<>();
    List<TreeBean> rootNodes = new ArrayList<>();

    public BuildTreeUtil(final List<TreeBean> nodes) {
        super();
        this.nodes = nodes;
    }

    public BuildTreeUtil(final List<TreeBean> nodes, final List<TreeBean> rootNodes) {
        super();
        this.nodes = nodes;
        this.rootNodes = rootNodes;
    }

    /**
     * 构建树形结构
     *
     * @return
     */
    public List<TreeBean> buildTree() {
        final List<TreeBean> GroupDTOs = new ArrayList<>();
        if (this.rootNodes.isEmpty()) {
            this.rootNodes = this.getRootNodes();
        }
        for (final TreeBean rootNode : this.rootNodes) {
            this.buildChildNodes(rootNode);
            GroupDTOs.add(rootNode);
        }
        return GroupDTOs;
    }

    /**
     * 递归子节点
     *
     * @param node
     */
    public void buildChildNodes(final TreeBean node) {
        final List<TreeBean> children = this.getChildNodes(node);
        if (!children.isEmpty()) {
            for (final TreeBean child : children) {
                this.buildChildNodes(child);
            }
            node.setChildren(children);
        }
    }

    /**
     * 获取父节点下所有的子节点
     *
     * @param nodes
     * @param pnode
     * @return
     */
    public List<TreeBean> getChildNodes(final TreeBean pnode) {
        final List<TreeBean> childNodes = new ArrayList<>();
        if (!this.isConstruct(pnode, "id")) {
            throw new UnitedException("构造树对象不存在id", new Object[] {});
        }
        for (final TreeBean n : this.nodes) {
            if (!this.isConstruct(n, "parentId")) {
                throw new UnitedException("构造树对象不存在parentId", new Object[] {});
            }
            if (pnode.getAttr().get("id").toString().equals(n.getAttr().get("parentId").toString())) {
                childNodes.add(n);
            }
        }
        return childNodes;
    }

    /**
     * 构造树依赖节点Id和父级节点Id
     *
     * @param node
     * @param key
     * @return
     */
    private boolean isConstruct(final TreeBean node, final String key) {
        if ((node.getAttr() == null) || (node.getAttr().get(key) == null)) {
            return false;
        }
        return true;
    }

    /**
     * 判断是否为根节点
     *
     * @param nodes
     * @param inNode
     * @return
     */
    public boolean rootNode(final TreeBean node) {
        boolean isRootNode = true;
        if (!this.isConstruct(node, "id")) {
            throw new UnitedException("构造树对象不存在id", new Object[] {});
        }
        for (final TreeBean n : this.nodes) {
            if (!this.isConstruct(n, "parentId")) {
                throw new UnitedException("构造树对象不存在parentId", new Object[] {});
            }
            if (node.getAttr().get("parentId").toString().equals(n.getAttr().get("id").toString())) {
                isRootNode = false;
                break;
            }
        }
        return isRootNode;
    }

    /**
     * 获取集合中所有的根节点
     *
     * @param nodes
     * @return
     */
    public List<TreeBean> getRootNodes() {
        final List<TreeBean> rootNodes = new ArrayList<>();
        for (final TreeBean n : this.nodes) {
            if (this.rootNode(n)) {
                rootNodes.add(n);
            }
        }
        return rootNodes;
    }
}
